# -*- coding: utf-8 -*-
"""
食堂菜单推荐系统

本程序提供两种使用方式：
1. 命令行界面（无需额外依赖，直接运行即可）
2. Gradio可视化界面（需要安装gradio：pip install gradio）

使用说明：
- 直接运行：python .gradio.py
- 如需使用Gradio界面，请确保已安装gradio并取消相应代码的注释
"""

import requests
import json
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 尝试导入gradio，如果失败则使用命令行界面
try:
    import gradio as gr
    GRADIO_AVAILABLE = True
except ImportError:
    print("注意：未找到gradio模块，将使用命令行界面。")
    print("如需使用图形界面，请运行: pip install gradio")
    GRADIO_AVAILABLE = False

def call_agent_api(user_question):
    """
    调用百度智能体API并返回响应结果
    """
    # 配置信息
    APP_ID = "9R6E1S5QaNUOGY7YinLjjHDUV49ZkVmM"
    SECRET_KEY = "hvZPgRzPcmS31ME4zqhKRzeDn5h3lKom"
    URL = f"https://agentapi.baidu.com/assistant/getAnswer?appId={APP_ID}&secretKey={SECRET_KEY}"

    # 请求头
    headers = {"Content-Type": "application/json"}

    # 请求体
    payload = {
        "message": {"content": {"type": "text", "value": {"showText": user_question}}},
        "source": APP_ID,
        "from": "openapi",
        "openId": "user_test_001",
    }

    # --- 增加重试机制 ---
    session = requests.Session()
    retry_strategy = Retry(
        total=3,  # 最大重试次数
        backoff_factor=1,  # 重试间隔时间（1秒，2秒，4秒...）
        status_forcelist=[429, 500, 502, 503, 504],  # 需要重试的状态码
        allowed_methods={"POST"},  # 仅对 POST 请求重试
    )
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("https://", adapter)

    # 发送请求
    try:
        response = session.post(
            URL, headers=headers, data=json.dumps(payload), timeout=60  # 超时时间增加到 60 秒
        )
        response.raise_for_status()
        result = response.json()

        if result.get("status") == 0:
            data = result.get("data", {})
            thread_id = data.get("threadId")
            
            # 提取回答
            answers = data.get("content", [])
            response_text = f"会话ID: {thread_id}\n\n"
            for idx, ans in enumerate(answers):
                data_type = ans.get("dataType")
                content = ans.get("data", "")
                # 兼容不同 dataType
                if isinstance(content, dict):
                    content = content.get("text", content)
                response_text += f"{content}\n"
            return response_text
        else:
            return f"请求失败: {result.get('status')} - {result.get('message')}"

    except requests.exceptions.RequestException as e:
        return f"网络请求异常: {e}"
    except json.JSONDecodeError:
        return "解析响应失败，返回内容不是 JSON"
    except Exception as e:
        return f"其他错误: {e}"

def create_interface():
    """
    创建食堂菜单推荐系统Gradio界面
    """
    with gr.Blocks(title="食堂菜单推荐系统", theme=gr.themes.Soft()) as interface:
        gr.Markdown("# 🍽️ 食堂菜单推荐系统")
        gr.Markdown("欢迎使用食堂菜单推荐系统！告诉我们您想吃什么，我们将为您推荐最适合的食堂菜品。")
        
        with gr.Row():
            with gr.Column(scale=1):
                # 添加菜品种类选择
                food_category = gr.Dropdown(
                    choices=["全部", "清淡食品", "肉类菜品", "素食", "汤类", "主食", "小吃"],
                    label="菜品类型",
                    value="全部"
                )
                
                # 添加价格范围选择
                price_range = gr.Dropdown(
                    choices=["不限", "10元以下", "10-15元", "15元以上"],
                    label="价格范围",
                    value="不限"
                )
                
                # 用户自定义问题输入
                user_input = gr.Textbox(
                    label="具体需求",
                    placeholder="例如：推荐一些好吃的红烧肉 / 今天想吃清淡的菜",
                    lines=3
                )
                
                submit_btn = gr.Button("获取推荐", variant="primary")
            
            with gr.Column(scale=2):
                # 使用Markdown组件显示菜单推荐，支持格式化显示
                response_output = gr.Markdown(
                    label="菜单推荐结果",
                    value="### 推荐结果将显示在这里\n\n请输入您的需求并点击获取推荐按钮。"
                )
        
        def generate_query(category, price, custom_query):
            """
            根据用户选择生成查询语句
            """
            query_parts = []
            
            if category != "全部":
                query_parts.append(f"推荐一些{category}")
            
            if price != "不限":
                query_parts.append(f"价格在{price}的菜品")
            
            if custom_query.strip():
                query_parts.append(custom_query.strip())
            
            # 如果没有任何输入，提供默认查询
            if not query_parts:
                return "推荐一些今天的特色菜品"
            
            return "，".join(query_parts)
        
        # 处理用户输入并调用API
        def process_request(category, price, custom_query):
            query = generate_query(category, price, custom_query)
            response = call_agent_api(query)
            # 移除会话ID部分，只保留实际内容
            if "会话ID:" in response:
                response = "\n".join(response.split("\n")[2:])
            # 确保响应是Markdown格式
            return f"### 为您推荐的菜单\n\n{response}"
        
        # 设置按钮点击事件
        submit_btn.click(
            fn=process_request,
            inputs=[food_category, price_range, user_input],
            outputs=response_output
        )
        
        # 设置回车键触发
        user_input.submit(
            fn=process_request,
            inputs=[food_category, price_range, user_input],
            outputs=response_output
        )
        
        # 示例问题
        gr.Markdown("### 快速示例")
        examples = [
            ["清淡食品", "不限", "有没有适合夏天吃的菜？"],
            ["肉类菜品", "10-15元", "推荐一些辣的肉菜"],
            ["素食", "10元以下", "有什么好吃的素菜？"],
            ["全部", "不限", "今天食堂有什么特色菜？"]
        ]
        gr.Examples(
            examples=examples,
            inputs=[food_category, price_range, user_input],
            outputs=response_output,
            fn=process_request
        )
    
    return interface

def command_line_interface():
    """
    命令行界面实现
    """
    print("🍽️  食堂菜单推荐系统")
    print("----------------------------------------")
    print("输入您的菜单需求，获取个性化推荐")
    print("(输入'退出'或'q'结束程序)")
    print("----------------------------------------")
    
    food_categories = ["全部", "清淡食品", "肉类菜品", "素食", "汤类", "主食", "小吃"]
    price_ranges = ["不限", "10元以下", "10-15元", "15元以上"]
    
    while True:
        print("\n请选择菜品类型:")
        for i, category in enumerate(food_categories):
            print(f"{i+1}. {category}")
        
        category_choice = input("请输入选项序号: ")
        try:
            category_idx = int(category_choice) - 1
            if 0 <= category_idx < len(food_categories):
                selected_category = food_categories[category_idx]
            else:
                print("输入无效，默认选择'全部'")
                selected_category = "全部"
        except ValueError:
            print("输入无效，默认选择'全部'")
            selected_category = "全部"
        
        print("\n请选择价格范围:")
        for i, price in enumerate(price_ranges):
            print(f"{i+1}. {price}")
        
        price_choice = input("请输入选项序号: ")
        try:
            price_idx = int(price_choice) - 1
            if 0 <= price_idx < len(price_ranges):
                selected_price = price_ranges[price_idx]
            else:
                print("输入无效，默认选择'不限'")
                selected_price = "不限"
        except ValueError:
            print("输入无效，默认选择'不限'")
            selected_price = "不限"
        
        custom_query = input("\n请输入具体需求（可选）: ")
        
        # 生成查询
        query_parts = []
        if selected_category != "全部":
            query_parts.append(f"推荐一些{selected_category}")
        if selected_price != "不限":
            query_parts.append(f"价格在{selected_price}的菜品")
        if custom_query.strip():
            query_parts.append(custom_query.strip())
        
        if not query_parts:
            query = "推荐一些今天的特色菜品"
        else:
            query = "，".join(query_parts)
        
        print(f"\n正在查询: {query}")
        print("----------------------------------------")
        
        # 调用API获取推荐
        response = call_agent_api(query)
        # 处理响应
        if "会话ID:" in response:
            response = "\n".join(response.split("\n")[2:])
        
        print("\n为您推荐的菜单:")
        print(response)
        print("----------------------------------------")
        
        # 询问是否继续
        next_action = input("\n按Enter继续查询，或输入'退出'/'q'结束: ").lower()
        if next_action in ['退出', 'q', 'quit', 'exit']:
            print("感谢使用食堂菜单推荐系统，再见！")
            break

if __name__ == "__main__":
    print("🍽️  食堂菜单推荐系统启动中...")
    
    # 如果有Gradio，则启动图形界面，否则启动命令行界面
    if GRADIO_AVAILABLE:
        try:
            interface = create_interface()
            print("界面创建成功，正在启动服务器...")
            # 使用默认配置启动，允许在本地访问
            interface.launch(share=False)  # 设置share=True可以生成临时公开链接
        except Exception as e:
            print(f"图形界面启动失败: {e}")
            print("正在切换到命令行界面...")
            command_line_interface()
    else:
        # 直接使用命令行界面
        command_line_interface()